package com.rlax.framework.support.sms.aliyun;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.fastjson.JSON;
import com.aliyun.mns.client.CloudAccount;
import com.aliyun.mns.client.CloudTopic;
import com.aliyun.mns.client.MNSClient;
import com.aliyun.mns.common.ServiceException;
import com.aliyun.mns.model.BatchSmsAttributes;
import com.aliyun.mns.model.MessageAttributes;
import com.aliyun.mns.model.RawTopicMessage;
import com.aliyun.mns.model.TopicMessage;
import com.rlax.framework.support.sms.SmsSender;

/**
 * 阿里云短信发送 - 基于消息服务版本SDK
 * 
 * @author Rlax
 * 
 */
public class AliyunMessageServiceSmsSender implements SmsSender {

	private static final Logger logger = LoggerFactory.getLogger(AliyunMessageServiceSmsSender.class);
	
    private String accessId;
    private String accessKey;
    private String mnsEndpoint;
    private String topic;
    
    private MNSClient client;
	
    public AliyunMessageServiceSmsSender(String accessId, String accessKey, String mnsEndpoint, String topic) {
    	this.accessId = accessId;
    	this.accessKey = accessKey;
    	this.mnsEndpoint = mnsEndpoint;
    	this.topic = topic;
    }
    
	@Override
	public void send(String phoneNo, String message) {
		
	}

	@Override
	public void send(List<String> phoneNo, String message) {
		
	}

	@Override
	public void send(String phoneNo, String signName, String templateCode, Map<String, String> params) {
		List<String> phoneNoList = new ArrayList<String>();
		phoneNoList.add(phoneNo);
		send(phoneNoList, signName, templateCode, params);
	}

	@Override
	public void send(List<String> phoneNoList, String signName, String templateCode, Map<String, String> params) {
		String paramString = JSON.toJSONString(params);
		if (phoneNoList == null || phoneNoList.size() == 0) {
			logger.error("发送短信号码为空：签名{}, 模版编码{}, 参数串{}", new String[]{signName, templateCode, paramString});
			return;
		}
		
    	/**
         * Step 1. 获取主题引用
         */
        CloudAccount account = new CloudAccount(accessId, accessKey, mnsEndpoint);
        client = account.getMNSClient();

		CloudTopic cloudTopic = client.getTopicRef(topic);
		
		/**
         * Step 2. 设置SMS消息体（必须）
         *
         * 注：目前暂时不支持消息内容为空，需要指定消息内容，不为空即可。
         */
        RawTopicMessage msg = new RawTopicMessage();
        msg.setMessageBody("sms-message");
        /**
         * Step 3. 生成SMS消息属性
         */
        MessageAttributes messageAttributes = new MessageAttributes();
        BatchSmsAttributes batchSmsAttributes = new BatchSmsAttributes();
        // 3.1 设置发送短信的签名（SMSSignName）
        batchSmsAttributes.setFreeSignName(signName);
        // 3.2 设置发送短信使用的模板（SMSTempateCode）
        batchSmsAttributes.setTemplateCode(templateCode);
        // 3.3 设置接收短信的手机号码（在短信模板中定义的）
        BatchSmsAttributes.SmsReceiverParams smsReceiverParams = new BatchSmsAttributes.SmsReceiverParams();
        for (String key : params.keySet()) {
        	smsReceiverParams.setParam(key, params.get(key));
        }
        // 3.4 增加接收短信的号码
		StringBuffer phoneStrs = new StringBuffer();
        for (String phoneNo : phoneNoList) {
            batchSmsAttributes.addSmsReceiver(phoneNo, smsReceiverParams);
            phoneStrs.append(phoneNo).append(",");
        }
        phoneStrs.substring(0, phoneStrs.length() - 1);
        messageAttributes.setBatchSmsAttributes(batchSmsAttributes);
        try {
            /**
             * Step 4. 发布SMS消息
             */
            TopicMessage ret = cloudTopic.publishMessage(msg, messageAttributes);
    		logger.info("发送短信：接收号码{}, 签名{}, 模版编码{}, 参数串{}", new String[]{phoneStrs.toString(), signName, templateCode, paramString});
    		logger.info("发送短信返回：MessageId{}, MessageMD5{}", new String[]{ret.getMessageId(), ret.getMessageBodyMD5()});
        } catch (ServiceException se) {
			logger.error("发送短信异常：code {}, message {}", new String[]{se.getErrorCode() + se.getRequestId(), se.getMessage()});
            se.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        client.close();	
	}

}
